<script setup lang="ts" name="GoodsSku">
import { GoodsInfo, Spec, SpecValue } from '@/types/goods'
import bwPowerSet from '@/utils/bwPowerSet'
// const res = bwPowerSet(['蓝色', '中国', '20cm'])
// console.log(res)

const props = defineProps<{
  goods: GoodsInfo,
  skuId?: string
}>()
const emit = defineEmits<{
  (e: 'changeGoods', value: string): void
}>()
//1.点击商品规格选中处理selected类名
const changeSelected = (sub: SpecValue, item: Spec) => {
  if (sub.disabled) return
  // 1. 点谁谁亮, 再点熄灭 为点击的项添加/移除selectd类名
  if (sub.selected) {
    sub.selected = false
  } else {
    // 干掉所有人, 复活我自己
    item.values.forEach(obj => obj.selected = false)
    sub.selected = true
  }
  // const arr = getSelectedSpec()
  // console.log(arr)
  SpecDisabled()
  //  子传父
  const resultArr = getSelectedSpec()
  // 判断resultArr中有没有'', 没有再发请求 或者 过滤一遍resultArr检测非空值
  // console.log(resultArr.includes(''));判断resultArr中有没有''
  const filterArr = resultArr.filter(v => v)
  if (filterArr.length === props.goods.specs.length) {
    // console.log(filterArr.length, '子传父 发送skuId');
    // 直接拿着resultArr处理成的字符串去字典中拿
    const key = filterArr.join('+')
    // console.log(pathMap[key][0]);
    const skuId = pathMap[key][0]
    emit('changeGoods', skuId)
  } else {
    emit('changeGoods', '')
  }

}
// 2. 获取路径字典处理函数
const getPathMap = () => {
  const pathMap: {
    [key: string]: string[]
  } = {} // 字典
  // console.log(props.goods.skus)
  // 2.1 过滤掉库存为0的sku
  const skus = props.goods.skus.filter(sku => sku.inventory > 0)
  // console.log(skus)
  // 2.2 将每一个sku的规格类型收集到一个数组中==> 求子集
  skus.forEach(sku => {
    const arr = sku.specs.map(spec => spec.valueName)
    // 2.3 求子集
    const sets = bwPowerSet(arr)
    // console.log(sets) 每一个sku的子集 
    // 将子集的情况处理成字符串往对象中加属性
    sets.forEach(set => {
      const key = set.join('+')
      // console.log(key) // 键
      // 判断对象是否有某个键, 没有就创建一个键, 有就追加值
      if (pathMap[key]) {
        // 追加
        pathMap[key].push(sku.id)
      } else {
        // 开一个属性存
        /* pathMap[key] = []
        pathMap[key].push(sku.id) */
        pathMap[key] = [sku.id]
      }
    })
  })
  return pathMap
}

// 5. 为点击切换准备有顺序的一个数组, 才能去字典中查找 // ['黑色']
const getSelectedSpec = () => {
  const arr: string[] = []
  props.goods.specs.forEach((spec, i) => {// 3种规格
    // console.log(spec.values)
    const btn = spec.values.find(btnObj => btnObj.selected)
    // 这种方式好理解
    if (btn) {
      arr[i] = btn.name
    } else {
      arr[i] = ''
    }
    // 便捷的方式
    // if (btn) arr.push(btn.name) // 只能保证数组有顺序
  })
  return arr
}
// 3. 页面一加载就获取路径字典
const pathMap = getPathMap()
console.log(pathMap)
// 4. 判断哪些按钮页面一加载就要被禁用
const SpecDisabled = () => {
  const arr = getSelectedSpec() // ['', '', '日本']
  // console.log(arr)
  props.goods.specs.forEach((spec, i) => { // spec是每一行
    spec.values.forEach(btnObj => { // 每一个规格按钮对象
      // console.log(btnObj.name) // 每一个规格按钮的名字
      // 检测按钮是否在字典中
      const newArr = [...arr] // ['', '', '日本'] // 备份模拟匹配的数组
      newArr[i] = btnObj.name
      // console.log(newArr); // newArr是点击按钮后可能匹配的情况
      const key = newArr.filter(v => v).join('+') // 处理空值的情况 '黑色' , '日本'  黑++日本
      // console.log(key)
      if (pathMap[key]) {
        btnObj.disabled = false
      } else {
        btnObj.disabled = true
      }
    })
  })
}
SpecDisabled()

// 默认选中商品规格  父传子 
const defaultSelect = () => {
  if (!props.skuId) return
  // 根据传递的skuId 去 skus中查找
  const sku = props.goods.skus.find(sku => sku.id === props.skuId)
  // 如果找到了 将对应每一行的规格的按钮 选中
  // console.log(sku)
  if (sku) {
    props.goods.specs.forEach((spec, i) => { // spec是每一行
      spec.values.forEach(value => {  // 每一个规格按钮对象
        console.log(value.name) // 每一个规格按钮的名字
        if (value.name === sku.specs[i].valueName) {
          value.selected = true
        }
      })
    })
  }
}
defaultSelect()
</script>
<template>
  <div class="goods-sku">
    <dl v-for="item in goods.specs" :key="item.id">
      <dt>{{ item.name }}</dt>
      <dd>
        <!-- selected  选择后的类名 绿色边框  disabled 表示禁用没货 不能点击-->
        <template v-for="sub in item.values" :key="sub.name">
          <!-- {{ sub }} -->
          <img v-if="sub.picture" :src="sub.picture" :class="{ selected: sub.selected, disabled: sub.disabled }"
            @click="changeSelected(sub, item)" />
          <span v-else :class="{ selected: sub.selected, disabled: sub.disabled }" @click="changeSelected(sub, item)">{{
              sub.name
          }}</span>
        </template>
      </dd>
    </dl>
  </div>
</template>

<style scoped lang="less">
.sku-state-mixin () {
  border: 1px solid #e4e4e4;
  margin-right: 10px;
  cursor: pointer;

  &.selected {
    border-color: @xtxColor;
  }

  &.disabled {
    opacity: 0.6;
    border-style: dashed;
    cursor: not-allowed;
  }
}

.goods-sku {
  padding-left: 10px;
  padding-top: 20px;

  dl {
    display: flex;
    padding-bottom: 20px;
    align-items: center;

    dt {
      width: 50px;
      color: #999;
    }

    dd {
      flex: 1;
      color: #666;

      >img {
        width: 50px;
        height: 50px;
        margin-top: 5px;
        .sku-state-mixin ();
      }

      >span {
        display: inline-block;
        height: 30px;
        line-height: 30px;
        padding: 0 20px;
        margin-top: 5px;
        .sku-state-mixin ();
      }
    }
  }
}
</style>
